package com.weilele.library.banner.impl.ybanner

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
import android.widget.LinearLayout.HORIZONTAL
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.weilele.mvvm.base.helper.ILifecycleObserver
import com.weilele.mvvm.utils.activity.findFragment
import com.weilele.mvvm.utils.activity.getActivity
import java.lang.ref.WeakReference
import kotlin.math.abs

class YBanner : FrameLayout, ILifecycleObserver {

    private var lifecycleOwner: LifecycleOwner? = null

    //是否可以滑动
    var isEnableScroll = true

    //滚动时长
    var autoScrollDuration = 1000

    //是否自动滚动
    var canAutoScroll = true
        set(value) {
            field = value
            if (value) {
                start()
            } else {
                stop()
            }
        }

    //自动滚动间隔
    var autoScrollInterval = 3000L

    val viewPager2 by lazy {
        ViewPager2(context).apply {
            layoutParams = LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT
            )
        }
    }
    internal val rcv by lazy { viewPager2.getChildAt(0) as RecyclerView }

    private val autoTask by lazy { AutoTask(WeakReference(this)) }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    init {
        addView(viewPager2)
        YScrollSpeedManger.reflectLayoutManager(this)
        val fragment = findFragment<Fragment>()
        if (fragment != null) {
            setLifecycle(fragment)
        } else {
            setLifecycle(getActivity())
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (!viewPager2.isUserInputEnabled) {
            return super.dispatchTouchEvent(ev)
        }
        val action = ev.actionMasked
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE) {
            start()
        } else if (action == MotionEvent.ACTION_DOWN) {
            stop()
        }
        return super.dispatchTouchEvent(ev)
    }

    private var mStartX = 0f
    private var mStartY = 0f
    private var mIsViewPager2Drag = false
    private val mTouchSlop by lazy { ViewConfiguration.get(context).scaledTouchSlop / 3 }
    override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
        if (!isEnableScroll) {
            return true
        }
        if (!viewPager2.isUserInputEnabled) {
            return super.onInterceptTouchEvent(event)
        }
        when (event!!.action) {
            MotionEvent.ACTION_DOWN -> {
                mStartX = event.x
                mStartY = event.y
                parent.requestDisallowInterceptTouchEvent(true)
            }
            MotionEvent.ACTION_MOVE -> {
                val endX = event.x
                val endY = event.y
                val distanceX: Float = abs(endX - mStartX)
                val distanceY: Float = abs(endY - mStartY)
                mIsViewPager2Drag = if (viewPager2.orientation == HORIZONTAL) {
                    distanceX > mTouchSlop && distanceX > distanceY
                } else {
                    distanceY > mTouchSlop && distanceY > distanceX
                }
                parent.requestDisallowInterceptTouchEvent(mIsViewPager2Drag)
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> parent.requestDisallowInterceptTouchEvent(
                false
            )
        }
        return super.onInterceptTouchEvent(event)
    }


    /**
     * 是否消费事件
     * 消费:事件就结束
     * 不消费:往父控件传
     */
    override fun onTouchEvent(ev: MotionEvent?): Boolean { //return false;// 可行,不消费,传给父控件
        //return true;// 可行,消费,拦截事件
        //super.onTouchEvent(ev); //不行,
        //虽然onInterceptTouchEvent中拦截了,
        //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法.
        return if (isEnableScroll) {
            super.onTouchEvent(ev)
        } else {
            true // 可行,消费,拦截事件
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stop()
    }

    override fun onStart() {
        super.onStart()
        start()
    }

    override fun onStop() {
        super.onStop()
        stop()
    }

    override fun onVisibilityChanged(changedView: View, visibility: Int) {
        super.onVisibilityChanged(changedView, visibility)
        if (changedView == this) {
            if (visibility == View.VISIBLE) {
                start()
            } else {
                stop()
            }
        }
    }


    private open class AutoTask(private val yBanner: WeakReference<YBanner>) : Runnable {
        override fun run() {
            yBanner.get()?.let {
                val adapter = it.viewPager2.adapter
                if (adapter != null) {
                    val next = it.viewPager2.currentItem + 1
                    if (next < adapter.itemCount) {
                        it.viewPager2.currentItem = next
                        it.postDelayed(it.autoTask, it.autoScrollInterval + it.autoScrollDuration)
                    }
                }

            }
        }
    }

    /*****************************支持对外调用****************************/
    fun start() {
        if (canAutoScroll) {
            this.let {
                stop()
                it.postDelayed(it.autoTask, it.autoScrollInterval + it.autoScrollDuration)
            }
        }
    }

    fun stop() {
        removeCallbacks(autoTask)
    }

    override fun onDestroy() {
        lifecycleOwner = null
        super.onDestroy()
    }

    fun setLifecycle(owner: LifecycleOwner?) {
        lifecycleOwner = if (owner == null) {
            lifecycleOwner?.lifecycle?.removeObserver(this)
            null
        } else {
            lifecycleOwner?.lifecycle?.removeObserver(this)
            owner.lifecycle.addObserver(this)
            owner
        }
    }
}